﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web.UI.WebControls;

using Infrastructure.NetExtensions;
using Infrastructure.Diagnostics;
using TempEmployees.DAL;
using TempEmployees.BLL;
using TempEmployees.BLL.Database;
using TempEmployees.BLL.EntitiesExtensions;
using TempEmployees.BLL.Validations;

namespace TempEmployees.Web
{
    public partial class AssignmentDetails : ABaseUserControl
    {
        private string AssignmentUserId
        {
            get { return ViewState.Get<string>("AssignmentUserId"); }
            set { ViewState.Set("AssignmentUserId", value); }
        }

        public bool IsReadOnly
        {
            get { return ViewState.Get<bool>("IsReadOnly"); }
            set
            {
                ViewState.Set("IsReadOnly", value);
                ReadOnlyControls(value);
            }
        }

        #region GUI

        private void SetDropDownLists()
        {
            DataDisplayBudgetType.SetDropDownList(
                (list) => DbServices.SetDropDownBudgetTypes(list));
            DataDisplayBudgetType.Items.RemoveAt(0);
            DataDisplayBudgetType.SelectedValue = (int)DbConstants.BudgetType.Technioni; //default is Technioni

            DataDisplaySemester.SetDropDownList(
                (list) => DbServices.SetDropDownSemesters(list, true));
            DataDisplaySemester.Items.RemoveAt(0);
            DropDownListSemesters_SelectedIndexChanged();
            SetSemesterVisibility();

            SetEmployersDropDown();
        }

        private void SetEmployersDropDown()
        {
            bool show = false;
            if (State.UserRole != DbConstants.Roles.Employer)
            {
                show = true;
                DataDisplayEmployer.SetDropDownList(
                    (list) => DbServices.SetDropDownUsers(list, DbServices.CHOOSE_EMPLOYER));
                DataDisplayEmployer.SelectedIndex = 0;
            }
            else
            {
                User user = EUser.GetUserById(State.UserId);
                DataDisplayEmployer.Items.Add(new ListItem(user.ToString(), user.ID));
            }
            DataDisplayEmployer.Visible = show;
            LabelEmployer.Visible = show;
        }

        private void SetBudgetNumberDropDown()
        {
            DataDisplayBudgetNumber.OptionalValue = -1;
            if (DataDisplayEmployer.SelectedValue == 0)
            {
                DataDisplayBudgetNumber.Items.Clear();
            }
            else
            {
                int budgetTypeId = (DataDisplayBudgetType.SelectedValue < 0) ? (int)DbConstants.BudgetType.Technioni : (int)DataDisplayBudgetType.SelectedValue;
                DataDisplayBudgetNumber.SetDropDownList(
                    (list) => DbServices.SetDropDownBudgets(list, AssignmentUserId, budgetTypeId));
                if (DataDisplayBudgetNumber.Items.Count > 0)
                {
                    DataDisplayBudgetNumber.SelectedIndex = 0;
                }
            }
        }

        private void SetSemesterVisibility()
        {
            bool show = !(DataDisplayBudgetType.SelectedValue == (int)DbConstants.BudgetType.Mosadi);
            DataDisplaySemester.Visible = show;
            LabelSemester.Visible = show;
        }

        public void ClearData()
        {
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                control.Reset();
            }

            //enable all the controls
            EnableControls(true);
        }

        public void EnableControls(bool enable)
        {
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                control.Enabled = enable;
            }
        }

        private void ReadOnlyControls(bool readOnly)
        {
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                if (control == DataDisplayEmployer && State.UserRole == DbConstants.Roles.Employer) continue;
                control.ReadOnly = readOnly;
            }
        }

        public void SetErrorPanel(List<string> errors)
        {
            GUIServices.SetErrorPanel(PanelAssignmentErrors, LabelError, errors, WebConfigData.MESSAGE_ERR_VALIDATION);
        }

        public void SetStatusVisibility(bool visible)
        {
            LabelStatus.Visible = visible;
        }

        private string SalaryToText(decimal salary)
        {
            string salaryStr = salary.ToString();
            return salaryStr.Remove(salaryStr.Length - 2);
        }

        private void TryParseTextBoxs(out decimal salary, out int monthlyHours,
            out DateTime startDate, out DateTime endDate)
        {
            if (DataDisplaySalary.IsDefaultValue) salary = 0;
            else if (!decimal.TryParse(DataDisplaySalary.Text, out salary)) salary = -1;

            if (!int.TryParse(DataDisplayMonthlyHours.Text, out monthlyHours)) monthlyHours = -1;

            DataDisplayStartDate.GetSelectedDate(out startDate);

            DataDisplayEndDate.GetSelectedDate(out endDate);
        }

        #endregion

        #region assignment methods

        private void SetAssignmentUserId(string id = null)
        {
            AssignmentUserId = (id != null) ? id :
                (State.UserRole == DbConstants.Roles.Employer) ? State.UserId : DataDisplayEmployer.SelectedValue.ToString();
            //according to the user, set his budgets numbers
            SetBudgetNumberDropDown();
        }

        public Assignment CreateAssignment(string employeeId)
        {
            if (!CheckRequiredFields() || !ValidateFields()) return null;
            int? prevAssignment = (LabelDisplayID.Visible) ? int.Parse(LabelDisplayID.Text) : default(int?);
            Assignment newAssignment = EAssignment.CreateAssignment(BudgetTypeId, BudgetNumber, Salary, SemesterId, MonthlyHours,
                StartDate, EndDate, AssignmentUserId, employeeId, prevAssignment);
            return newAssignment;
        }

        public bool UpdateAssignment(int assignmentId)
        {
            Assignment assignment = EAssignment.GetAssignmentById(assignmentId);
            if (assignment == null || !CheckRequiredFields() || !ValidateFields()) return false;

            assignment.SetBudgetNumber(BudgetNumber, BudgetTypeId);
            assignment.SetSalary(DataDisplaySalary.IsDefaultValue, Salary);
            assignment.MonthlyHours = MonthlyHours;
            assignment.StartDate = StartDate;
            assignment.EndDate = EndDate;
            assignment.SemesterID = SemesterId;

            Assignment updatedAssignment;
            return EAssignment.UpdateAssignment(assignment, out updatedAssignment);
        }

        private bool CheckRequiredFields()
        {
            List<string> errors = new List<string>();
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                if (control.Required && !control.IsFilled()) errors.Add(control.DisplayName);
            }
            if (errors.Count > 0)
            {
                GUIServices.SetErrorPanel(PanelAssignmentErrors, LabelError, errors, GUIServices.MESSAGE_ERR_REQUIRED);
                return false;
            }
            GUIServices.SetErrorPanel(PanelAssignmentErrors, LabelError, errors, "");
            return true;
        }

        private bool ValidateFields()
        {
            List<string> errors = new List<string>();
            foreach (BaseDataDisplay control in Controls.OfType<BaseDataDisplay>())
            {
                if (control.IsFilled() && !control.IsValid()) errors.Add(control.DisplayName);
            }
            if (!ValidationMethods.ValidateStartEndDates(StartDate, EndDate, DataDisplaySemester.SelectedValue, (DbConstants.BudgetType)(int)DataDisplayBudgetType.SelectedValue)) errors.Add("תאריכי העסקה");
            if (errors.Count > 0)
            {
                GUIServices.SetErrorPanel(PanelAssignmentErrors, LabelError, errors, GUIServices.MESSAGE_ERR_VALIDATION);
                return false;
            }
            else
            {
                GUIServices.SetErrorPanel(PanelAssignmentErrors, LabelError, errors, "");
                return true;
            }
        }

        public bool FillAssignmentDetails(int assignmentId)
        {
            Assignment assignment = EAssignment.GetAssignmentById(assignmentId);
            if (assignment == null) return false;

            //assignment ID
            LabelAssignmentId.Visible = true;
            LabelDisplayID.Visible = true;
            LabelDisplayID.Text = assignment.ID.ToString();
            //budget type
            DataDisplayBudgetType.SelectedValue = assignment.Budget.TypeID;
            //users 
            SetEmployersDropDown();
            SetAssignmentUserId(assignment.UserID);
            DataDisplayEmployer.SelectedValue = AssignmentUserId;
            //budget number
            SetBudgetNumberDropDown();
            DataDisplayBudgetNumber.SelectedValue = assignment.BudgetID;
            //salary
            if (assignment.Salary == 0) DataDisplaySalary.IsDefaultValue = true;
            else DataDisplaySalary.Text = SalaryToText(assignment.Salary);
            //semester
            DataDisplaySemester.SelectedValue = assignment.SemesterID;
            //monthly hours
            DataDisplayMonthlyHours.Text = assignment.MonthlyHours.ToString();
            //assignment dates
            DataDisplayStartDate.SelectedDate = assignment.StartDate;
            DataDisplayEndDate.SelectedDate = assignment.EndDate;
            //assignment status
            LabelDisplayStatus.Text = assignment.Status.Name;
            //comment
            TextBoxComment.Text = EAssignment.GetNotes(assignmentId);
            TextBoxComment.ReadOnly = true;
            ButtonToggleComment.Visible = true;

            return true;
        }

        #endregion

        #region comments

        public string CommentText { get { return TextBoxComment.Text; } }

        protected void ButtonToggleComment_Click(object sender, EventArgs e)
        {
            ToggleCommentField(!TextBoxComment.ReadOnly);
        }

        protected void ButtonAddComment_Click(object sender, EventArgs e)
        {
            int assignmentId;
            if (!int.TryParse(LabelDisplayID.Text, out assignmentId)) return;
            EAssignment.InsertComment(assignmentId, State.UserId, TextBoxComment.Text);
            ToggleCommentField(true);
        }

        protected void ToggleCommentField(bool read)
        {
            int assignmentId;
            TextBoxComment.ReadOnly = read;
            ButtonAddComment.Visible = !read;
            TextBoxComment.Text = (read && int.TryParse(LabelDisplayID.Text, out assignmentId)) ? EAssignment.GetNotes(assignmentId) : string.Empty;
            ButtonToggleComment.Text = (read) ? "מצב כתיבה" : "מצב קריאה";
        }

        #endregion

        #region Events

        protected void Page_Load(object sender, EventArgs e)
        {
            DataDisplayBudgetType.OnSelectedIndexChanged = DropDownListBudgetType_SelectedIndexChanged;
            DataDisplayEmployer.OnSelectedIndexChanged = DropDownListEmployers_SelectedIndexChanged;
            DataDisplaySemester.OnSelectedIndexChanged = DropDownListSemesters_SelectedIndexChanged;

            if (!this.IsPostBack)
            {
                ViewState.Set("IsReadOnly", false);

                SetDropDownLists();
                SetAssignmentUserId();

                //DataDisplaySalary.DefaultValue = string.Format("(שכר סטודנט) {0}", SalaryToText(EBaseSalary.CurrentBaseSalary.Salary));
                DataDisplaySalary.DefaultValue = SalaryToText(EBaseSalary.CurrentBaseSalary.Salary);
            }
        }

        protected void DropDownListEmployers_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetAssignmentUserId();
        }

        protected void DropDownListBudgetType_SelectedIndexChanged(object sender, EventArgs e)
        {
            SetSemesterVisibility();
            SetBudgetNumberDropDown();
        }

        protected void DropDownListSemesters_SelectedIndexChanged(object sender = null, EventArgs e = null)
        {
            try
            {
                DateTime start;
                DateTime end;
                ESemester.GetDates(DataDisplaySemester.SelectedValue, out start, out end);
                DataDisplayStartDate.SelectedDate = start;
                DataDisplayEndDate.SelectedDate = end;
            }
            catch (Exception ex)
            {
                Logger.ExceptionMessage(ex);
            }
        }

        #endregion

        #region assignment details - from controls to db type

        private int BudgetTypeId { get { return DataDisplayBudgetType.SelectedValue; } }
        private int SemesterId { get { return DataDisplaySemester.SelectedValue; } }
        private string BudgetNumber { get { return DataDisplayBudgetNumber.Text; } }
        private decimal Salary { get { return decimal.Parse(DataDisplaySalary.SelectedValue); } }
        private int MonthlyHours { get { return int.Parse(DataDisplayMonthlyHours.Text); } }
        private DateTime StartDate
        {
            get
            {
                DateTime startDate;
                DataDisplayStartDate.GetSelectedDate(out startDate);
                return startDate;
            }
        }
        private DateTime EndDate
        {
            get
            {
                DateTime endDate;
                DataDisplayEndDate.GetSelectedDate(out endDate);
                return endDate;
            }
        }

        #endregion
    }
}